;;; guix-config --- additional software for a custom configuration of gnu-guix
;;; Copyright © 2020 Kolya <kolya.daemon@vfemail.net>
;;;
;;; This file is part of guix-config
;;;
;;; guix-config is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; guix-config is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (kolyad systems workstation)
  #:use-module ((kolyad etc workstation) #:prefix etc:)
  #:use-module (kolyad packages linux)
  #:use-module (kolyad packages firmware)
  #:use-module (kolyad utils)
  #:use-module (gnu bootloader)
  #:use-module (gnu bootloader grub)
  #:use-module (gnu packages)
  #:use-module (gnu packages admin)        ;for wpa_supplicant
  #:use-module (gnu packages base)
  #:use-module (gnu packages bash)
  #:use-module (gnu packages cups)
  #:use-module (gnu packages firmware)
  #:use-module (gnu packages freedesktop)
  #:use-module (gnu packages gnome)
  #:use-module (gnu packages linux)
  #:use-module (gnu packages nvi)
  #:use-module (gnu packages shells)
  #:use-module (gnu packages texinfo)
  #:use-module (gnu packages zile)
  #:use-module (gnu services)
  #:use-module (gnu services base)
  #:use-module (gnu services mcron)
  #:use-module (gnu services networking)   ;for dhcpd, wpa-supplicant, network-manager, nftables
  #:use-module (gnu services admin)        ;for rottlog
  #:use-module (gnu services cups)
  #:use-module (gnu services dbus)
  #:use-module (gnu services desktop)      ;for elogind, bluetooth
  #:use-module (gnu services dns)          ;for knot-resolver
  #:use-module (gnu services pm)           ;for tlp
  #:use-module (gnu services sddm)
  #:use-module (gnu services sound)
  #:use-module (gnu services sysctl)
  #:use-module (gnu services xorg)
  #:use-module (gnu system)
  #:use-module (gnu system file-systems)
  #:use-module (gnu system linux-initrd)   ;for base-initrd
  #:use-module (gnu system mapped-devices)
  #:use-module (gnu system shadow)
  #:use-module (gnu system uuid)
  #:use-module (guix gexp)
  #:use-module (srfi srfi-1)
  #:export (%workstation-syscrypt
            %workstation-root-file-system
            %workstation-gnu-file-system
            %workstation-var-file-system
            %workstation-swap-file-system
            %workstation-home-file-system
            %workstation-esp-file-system
            %workstation-swap-space

            %workstation-bootloader

            %workstation-user-accounts
            %workstation-user-groups
            %workstation-skeletons

            %workstation-system-packages
            %workstation-base-packages
            %workstation-packages

            %subid-files-service
            %sysctl-ssd
            %sysctl-ssd-service

            %bluetooth-services
            %workstation-sysctl-services
            %workstation-desktop-services
            %workstation-system-services
            %workstation-base-services
            %workstation-services))


;;;
;;; Workstation file-systems
;;;
(define %workstation-syscrypt
  (mapped-device
    (source (uuid "b9f6111a-846f-49a6-b6aa-d188c96ef621"))
    (target "syscrypt")
    (type luks-device-mapping)))

(define %workstation-root-file-system
  (file-system
    (device "/dev/mapper/syscrypt")
    (mount-point "/")
    (type "btrfs")
    (options "compress=lzo,subvol=@")
    (dependencies (list %workstation-syscrypt))))
(define %workstation-gnu-file-system
  (file-system
      (device "/dev/mapper/syscrypt")
      (mount-point "/gnu")
      (type "btrfs")
      (options "compress=lzo,subvol=@gnu")
      (create-mount-point? #t)
      (dependencies (list %workstation-syscrypt))))
(define %workstation-var-file-system
  (file-system
    (device "/dev/mapper/syscrypt")
    (mount-point "/var")
    (type "btrfs")
    (options "compress=lzo,subvol=@var")
    (needed-for-boot? #t)
    (create-mount-point? #t)
    (dependencies (list %workstation-syscrypt))))
(define %workstation-swap-file-system
  (file-system
    (device "/dev/mapper/syscrypt")
    (mount-point "/swap")
    (type "btrfs")
    (options "compress=no,subvol=@swap")            ; swapfile with xattrs +C, +X
    (create-mount-point? #f)                        ; swapfile must be manually set up
    (dependencies (list %workstation-syscrypt))))
(define %workstation-home-file-system
  (file-system
    (device "/dev/mapper/syscrypt")
    (mount-point "/home")
    (type "btrfs")
    (options "compress=lzo,subvol=@home")
    (create-mount-point? #t)
    (dependencies (list %workstation-syscrypt))))
(define %workstation-esp-file-system
  (file-system
    (device (file-system-label "ESP"))
    (mount-point "/boot/efi")
    (type "vfat")
    (create-mount-point? #t)))

(define %workstation-swap-space
  (swap-space
    (target (string-append (file-system-mount-point %workstation-swap-file-system) "/swapfile"))
    (dependencies (list %workstation-swap-file-system))))


;;;
;;; Bootstrap
;;;
(define %workstation-bootloader
  (bootloader-configuration
    (bootloader grub-efi-bootloader)
    (targets (list (file-system-mount-point %workstation-esp-file-system)))))


;;;
;;; Workstation datafiles
;;;
(define %workstation-user-accounts
  (cons*
    (user-account
      (name "kolyad")
      (group "users")
      (supplementary-groups '("wheel"
                              "audio"
                              "cdrom"
                              "kvm"
                              "lp"
                              "netdev"
                              "video")))
    %base-user-accounts))

(define %workstation-user-groups %base-groups)

(define %workstation-skeletons '())


;;;
;;; Packages & Profiles
;;;
(define %workstation-system-packages
  (map specification->package+output
     '(
       "glibc"
       "nss-certs"
       "openssl"

       "bash"

       "grub-efi"
       "efibootmgr"
       "btrfs-progs"
       "cryptsetup"

       "cups"
       "tlp"
       "polkit"

       "dosfstools"
       "smartmontools"
       "brightnessctl"
                      )))
(define %workstation-base-packages
  (delete-and-replace-all
    `(,bash-completion ,wireless-tools)
    `((,zile ,nvi))
    %base-packages))
(define %workstation-packages
  (append %workstation-system-packages
          %workstation-base-packages))


;;;
;;; Services
;;;

(define %subid-files-service
  (service special-files-service-type
              ;; IDs should be greater than (@ (guix build accounts) %id-max)
            `(("/etc/subuid" ,(etc:subid-file "subuid" 100000 65536 %workstation-user-accounts))
              ("/etc/subgid" ,(etc:subid-file "subgid" 100000 65536 %workstation-user-accounts)))))

(define %sysctl-ssd
  (list '("vm.swappiness" . "1")))

(define %sysctl-ssd-service
  (service sysctl-service-type
    (sysctl-configuration
      (settings %sysctl-ssd))))


(define %bluetooth-services
  (list (bluetooth-service)))

(define %workstation-sysctl-services
  (list %sysctl-ssd-service))

(define %workstation-desktop-services
  (list
    (elogind-service)

    (service ntp-service-type)

    (service polkit-service-type)
    polkit-wheel-service
    (service cups-pk-helper-service-type)

    (service upower-service-type)

    (service cups-service-type
             (cups-configuration
               (web-interface? #t)
               (extensions (list cups-filters epson-inkjet-printer-escpr hplip-minimal))))
    (service sane-service-type)))

(define %workstation-system-services
  (list
    (service network-manager-service-type
      (network-manager-configuration
        (dns "none")
        (vpn-plugins
          (list network-manager-openvpn))))
    (service wpa-supplicant-service-type
      (wpa-supplicant-configuration
        (dbus? #t)
        (config-file etc:%wpa-supplicant-conf-file)))
    (service nftables-service-type
             (nftables-configuration
               (ruleset etc:%nftables-ruleset-file)))
    (service knot-resolver-service-type
             (knot-resolver-configuration
               (kresd-config-file etc:%kresd-conf-file)))
    (dbus-service)
    (udisks-service)
    %subid-files-service))

(define %workstation-base-services
  (list (service login-service-type
                 (login-configuration (motd etc:%kolyad-motd-file)))
        (service virtual-terminal-service-type)
        (service console-font-service-type
                 (map (lambda (tty)
                        (cons tty %default-console-font))
                   '("tty1" "tty2")))
        (service mingetty-service-type (mingetty-configuration
                                         (tty "tty1")))
        (service mingetty-service-type (mingetty-configuration
                                         (tty "tty2")))
        (service static-networking-service-type
          (list
            (static-networking
              (addresses (list (network-address
                                (device "lo")
                                (value "127.0.0.1/8"))))
              (requirement '())
              (provision '(loopback)))))
        (syslog-service (syslog-configuration
                          (config-file etc:%syslog-conf-file)))
        (service urandom-seed-service-type)
        (service guix-service-type)
        (service nscd-service-type)

        (service rottlog-service-type)

        ;; The LVM2 rules are needed as soon as LVM2 or the device-mapper is
        ;; used, so enable them by default.  The FUSE and ALSA rules are
        ;; less critical, but handy.
        (service udev-service-type
                 (udev-configuration
                   (rules (list lvm2 fuse alsa-utils crda brightnessctl))))

        (service special-files-service-type
                 `(("/usr/bin/env" ,(file-append (canonical-package coreutils)
                                                 "/bin/env"))
                   ("/bin/sh" ,(file-append (canonical-package bash)
                                            "/bin/bash"))))))

(define %workstation-services
  (append %workstation-system-services
          %workstation-base-services))

;;; vim: set expandtab tabstop=2 shiftwidth=2
;;; end of file workstation.scm
